/*
 * message_queue.c
 *
 *  Created on: 2017-4-6
 *      Author: chenshisheng
 */

#include "message_queue.h"
#include "package_buffer.h"

#include <string.h>

/// 消息队列缓存大小（字节）
#define BUFFER_SIZE 1024

// 默认的消息处理函数
static MsgQueue_Notify_t _globalNotify;

// 消息队列缓存
static uint8_t _buf[BUFFER_SIZE];

// 消息队列结构
static pbuf_t _pbuf;

static void _DefaultNotify(MsgQueue_Msg_t *msg);

void MsgQueue_Init(MsgQueue_Notify_t globalNotify)
{
    _globalNotify = globalNotify ? globalNotify : _DefaultNotify;

    PackageBuffer_Init(& _pbuf, _buf, sizeof(_buf), MSGQUEUE_MSG_MAX_SIZE);
}

int MsgQueue_Send(int id, const void *dataIn, unsigned int size)
{
    int ret;

    ENTER_CRITICAL_SECTION();
    ret = PackageBuffer_Write(& _pbuf, & id, sizeof(id));
    if(ret == 0)
    {
        ret = PackageBuffer_Write(& _pbuf, dataIn, size);
    }
    EXIT_CRITICAL_SECTION();
//    debug("MQ: Push msg id: %d\n", id);

    return ret;
}

int MsgQueue_Recv(MsgQueue_Msg_t *msgOut)
{
    int ret;
    uint8_t buf[MSGQUEUE_MSG_MAX_SIZE];
    unsigned int size;

    ENTER_CRITICAL_SECTION();
    ret = PackageBuffer_Read(& _pbuf, buf, & size);
    if((ret == 0) && (size == sizeof(msgOut->id)))
    {
//        msgOut->id = *((MsgQueue_Id_t *) buf);
        memcpy(& msgOut->id, buf, sizeof(msgOut->id));
        ret = PackageBuffer_Read(& _pbuf, msgOut->data, & msgOut->size);
    }
    else
    {
        ret = -1;
    }
    EXIT_CRITICAL_SECTION();

//    debug("MQ: Pop msg id: %d\n", msgOut->id);

    return ret;
}

static void _DefaultNotify(MsgQueue_Msg_t *msg)
{
    (void)msg;
    debug("Msg id = %d, size = %u\n", msg->id, msg->size);
}

void MsgQueue_Service(void)
{
    MsgQueue_Msg_t msg;

    while(MsgQueue_Recv(& msg) == 0)
    {
        _globalNotify(& msg);
    }
}
